package com.apobates.forum.thrones.admin.controller;

import com.apobates.forum.core.ImageIOMeta;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.apobates.forum.core.entity.Board;
import com.apobates.forum.core.entity.BoardConfig;
import com.apobates.forum.core.entity.BoardGroup;
import com.apobates.forum.core.entity.BoardStats;
import com.apobates.forum.core.entity.ForumEntityStatusEnum;
import com.apobates.forum.core.service.BoardConfigService;
import com.apobates.forum.core.service.BoardGroupService;
import com.apobates.forum.core.service.BoardService;
import com.apobates.forum.core.service.BoardStatsService;
import com.apobates.forum.event.elderly.ActionEventCulpritor;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.storage.core.MemberSessionBean;
import com.apobates.forum.thrones.admin.controller.form.BoardConfigForm;
import com.apobates.forum.thrones.admin.controller.form.BoardForm;
import com.apobates.forum.utils.lang.CommonBean;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.TipMessage;
import com.apobates.forum.utils.lang.EnumArchitecture;
import java.util.Optional;
import javax.validation.Valid;
import org.springframework.validation.BindingResult;

/**
 * 版块控制器
 *
 * @author xiaofanku@live.cn
 * @since 20190321
 */
@Controller
@RequestMapping(value = "/board")
public class AdminBoardController {
    @Autowired
    private BoardService boardService;
    @Autowired
    private BoardGroupService boardGroupService;
    @Autowired
    private BoardConfigService boardConfigService;
    @Autowired
    private BoardStatsService boardStatsService;
    @Autowired
    private ImageIOMeta imageIOMeta;
    private final static Logger logger = LoggerFactory.getLogger(AdminBoardController.class);
    
    //版块
    @GetMapping(path = "/")
    public String listPage(
            @RequestParam(name = "volume", required = false, defaultValue = "-1") int volumesId,
            HttpServletRequest request,
            Model model) {
        Stream<Board> rs = (volumesId >= 0) ? boardService.getAllByVolumesId(volumesId) : boardService.getAll();
        model.addAttribute("rs", rs.collect(Collectors.toList()));
        model.addAttribute("paramVolumes", volumesId);
        //举报话题类型是否被关联了提示
        //意见反馈话题类型是否被关联了提示
        return "admin/board/index";
    }
    //编辑版块
    @GetMapping(path = "/edit")
    public String boardForm(
            @RequestParam(name = "id", required = false, defaultValue = "0") long id,
            @RequestParam(name = "volume", required = false, defaultValue = "-1") int volumesId,
            HttpServletRequest request,
            Model model) {
        BoardForm form = new BoardForm();
        Board b = boardService.get(id).orElse(Board.empty(id));
        form.setRecord(id);
        form.setTitle(b.getTitle());
        form.setDescription(b.getDescription());
        form.setImageAddr(b.getImageAddr()); //编码后的图标图片地址|解码由标签负责
        form.setEntityStatus(b.getStatus());
        form.setRanking(b.getRanking() + "");
        form.setVolumesId(b.getVolumesId() + "");
        if (id == 0 && volumesId > 0) {
            form.setVolumesId(volumesId + "");
        }
        model.addAttribute("form", form);
        //
        model.addAttribute("boardStatusData", EnumArchitecture.getInstance(ForumEntityStatusEnum.class));
        return "admin/board/edit";
    }
    
    @PostMapping(path = "/edit")
    public String boardAction(
            HttpServletRequest request,
            @Valid @ModelAttribute("form") BoardForm form,
            BindingResult bindingResult,
            Model model) {
        if (bindingResult.hasErrors()) {
            model.addAttribute("form", form);
            //
            model.addAttribute("boardStatusData", EnumArchitecture.getInstance(ForumEntityStatusEnum.class));
            return "admin/board/edit";
        }
        Board b = new Board();
        b.setTitle(form.getTitle());
        b.setDescription(form.getDescription());
        b.setRanking(form.getIntegerRanking());
        b.setVolumesId(form.getIntegerVolumesId()); //没有选择时为默认版块组
        b.setStatus(form.getEnumEntityStatus());
        //------------------------------------------------------------编码图标图片的地址
        String icoImageAddr = form.getEncodeIcoAddr(imageIOMeta).orElse(null);
        logger.info("[AFU][B-CTL]encode image addr: " + icoImageAddr);
        if (null != icoImageAddr) {
            b.setImageAddr(icoImageAddr);
        }
        //------------------------------------------------------------
        boolean symbol;
        if (form.isUpdate()) {
            symbol = boardService.edit(form.getLongRecord(), b).orElse(false);
        } else {
            symbol = boardService.create(b.getVolumesId(), b.getTitle(), b.getDescription(), b.getImageAddr(), b.getStatus(), b.getRanking()).isPresent();
        }
        if (symbol) {
            return "redirect:/board/?volume=" + b.getVolumesId();
        }
        model.addAttribute("errors", form.getActionTitle() + "版块操作失败");
        model.addAttribute("form", form);
        //
        model.addAttribute("boardStatusData", EnumArchitecture.getInstance(ForumEntityStatusEnum.class));
        return "admin/board/edit";
    }
    //版块的配置
    @GetMapping(path = "/config")
    public String boardConfigForm(
            @RequestParam("id") long boardId,
            @RequestParam("volumes") int boardGroupId,
            HttpServletRequest request,
            Model model) {
        BoardConfigForm form = new BoardConfigForm();
        BoardConfig config = boardConfigService.getByBoardId(boardId).orElse(BoardConfig.defaultConfig(boardId));
        //boolean
        form.setReadWrite(config.isReadWrite());
        form.setIpFilter(config.isIpFilter());
        //读
        form.setReadMinScore(config.getReadMinScore() + "");
        form.setReadLowMemberGroup(config.getReadLowMemberGroup().getSymbol() + "");
        form.setReadLowMemberRole(config.getReadLowMemberRole().getSymbol() + "");
        form.setReadLowMemberLevel(config.getReadLowMemberLevel() + "");
        //写
        form.setEditMinute(config.getEditMinute() + "");
        form.setWriteMinInterrupt(config.getWriteMinInterrupt() + "");
        form.setWriteMinScore(config.getWriteMinScore() + "");
        form.setWriteLowMemberGroup(config.getWriteLowMemberGroup().getSymbol() + "");
        form.setWriteLowMemberRole(config.getWriteLowMemberRole().getSymbol() + "");
        form.setWriteLowMemberLevel(config.getWriteLowMemberLevel() + "");
        //
        form.setRecord(config.getId());
        form.setBoardId(boardId + "");
        form.setVolumesId(boardGroupId + "");
        model.addAttribute("form", form);
        //
        model.addAttribute("memberGroupData", EnumArchitecture.getInstance(MemberGroupEnum.class));
        model.addAttribute("memberRoleData", EnumArchitecture.getInstance(MemberRoleEnum.class));
        return "admin/board/config";
    }
    
    @PostMapping(path = "/config")
    public String boardConfigAction(
            @ModelAttribute("form") BoardConfigForm form,
            MemberSessionBean mbean,
            HttpServletRequest request,
            Model model) {
        long boardId = form.getLongBoardId();
        if (boardId == 0) {
            model.addAttribute("form", form);
            model.addAttribute("errors", "版块参数丢失");
            //
            model.addAttribute("memberGroupData", EnumArchitecture.getInstance(MemberGroupEnum.class));
            model.addAttribute("memberRoleData", EnumArchitecture.getInstance(MemberRoleEnum.class));
            return "admin/board/config";
        }
        BoardConfig config = new BoardConfig();
        config.setBoardId(boardId);
        //boolean
        config.setReadWrite(form.getBooleanReadWrite());
        config.setIpFilter(form.getBooleanIpFileter());
        //读
        config.setReadMinScore(form.getIntegerReadMinScore());
        MemberGroupEnum rmg = EnumArchitecture.getInstance(form.getIntegerReadLowMemberGroup(), MemberGroupEnum.class).orElse(MemberGroupEnum.GUEST);
        config.setReadLowMemberGroup(rmg);
        MemberRoleEnum rmr = EnumArchitecture.getInstance(form.getIntegerReadLowMemberRole(), MemberRoleEnum.class).orElse(MemberRoleEnum.NO);
        config.setReadLowMemberRole(rmr);
        config.setReadLowMemberLevel(form.getIntegerReadLowMemberLevel());
        //写
        config.setEditMinute(form.getIntegerEditMinute());
        config.setWriteMinInterrupt(form.getIntegerWriteMinInterrupt());
        config.setWriteMinScore(form.getIntegerWriteMinScore());
        MemberGroupEnum wmg = EnumArchitecture.getInstance(form.getIntegerWriteLowMemberGroup(), MemberGroupEnum.class).orElse(MemberGroupEnum.CARD);
        config.setWriteLowMemberGroup(wmg);
        MemberRoleEnum wmr = EnumArchitecture.getInstance(form.getIntegerWriteLowMemberRole(), MemberRoleEnum.class).orElse(MemberRoleEnum.NO);
        config.setWriteLowMemberRole(wmr);
        config.setWriteLowMemberLevel(form.getIntegerWriteLowMemberLevel());
        
        Optional<Boolean> data;
        if (form.isUpdate()) {
            //long id, int boardGroupId, long configId, BoardConfig updateConfig, ActionEventCulpritor culpritor
            ActionEventCulpritor aec = AdminHomeController.getActionCulpritor(mbean.getMid(), mbean.getNickname(), request, form.getToken());
            data = boardService.editBoardConfig(
                    form.getLongBoardId(),
                    form.getIntegerVolumesId(),
                    form.getLongRecord(),
                    config,
                    aec);
        } else {
            data = boardConfigService.create(config.getBoardId(), config);
        }
        if (data.orElse(false)) {
            return "redirect:/board/";
        }
        model.addAttribute("errors", "版块设置操作失败");
        model.addAttribute("form", form);
        //
        model.addAttribute("memberGroupData", EnumArchitecture.getInstance(MemberGroupEnum.class));
        model.addAttribute("memberRoleData", EnumArchitecture.getInstance(MemberRoleEnum.class));
        return "admin/board/config";
    }
    //所有版块
    @GetMapping(path = "/json", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Map<Long, String> getAllBoardForJson(HttpServletRequest request, Model model) {
        return boardService.getAll().collect(Collectors.toMap(Board::getId, Board::getTitle));
    }
    //版块统计
    @GetMapping(path = "/stats")
    public String getBoardStats(
            @RequestParam("id") long boardId,
            @RequestParam("volume") int boardGroupId,
            HttpServletRequest request,
            Model model) {
        BoardStats bs = boardStatsService.getByBoard(boardId).orElse(new BoardStats(boardId, boardGroupId));
        model.addAttribute("stats", bs);
        return "admin/board/stats";
    }
    //锁定
    @PostMapping(path = "/lock", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public TipMessage lockBoardAction(
            @RequestParam("id") long boardId,
            @RequestParam("volumes") int boardGroupId,
            MemberSessionBean mbean,
            HttpServletRequest request,
            Model model) {
        ActionEventCulpritor aec = AdminHomeController.getActionCulpritor(mbean.getMid(), mbean.getNickname(), request, "");
        return TipMessage.Builder.take(()->boardService.lock(boardId, boardGroupId, aec)).success("成功锁定版块").error("操作失败");
    }
    //解锁
    @PostMapping(path = "/lock/remove", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public TipMessage removeLockBoardAction(
            @RequestParam("id") long boardId,
            @RequestParam("volumes") int boardGroupId,
            MemberSessionBean mbean,
            HttpServletRequest request,
            Model model) {
        ActionEventCulpritor aec = AdminHomeController.getActionCulpritor(mbean.getMid(), mbean.getNickname(), request, "");
        return TipMessage.Builder.take(()->boardService.releaseLock(boardId, boardGroupId, aec)).success("成功解锁版块").error("操作失败");
    }
    //删除
    @PostMapping(path = "/remove", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public TipMessage removeBoardAction(
            @RequestParam("id") long boardId,
            @RequestParam("volumes") int boardGroupId,
            MemberSessionBean mbean,
            HttpServletRequest request,
            Model model) {
        ActionEventCulpritor aec = AdminHomeController.getActionCulpritor(mbean.getMid(), mbean.getNickname(), request, "");
        return TipMessage.Builder.take(()->boardService.remove(boardId, boardGroupId, aec)).success("版块删除成功").error("操作失败");
    }
    //查看指定的版块的名称
    @GetMapping(path = "/list.json", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Map<Long, String> getAllForIdJson(
            @RequestParam("ids") String idString,
            HttpServletRequest request,
            Model model) {
        return boardService.getAllById(Commons.toLongSet(idString));
    }
    
    @GetMapping(path = "/lazy.json", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Map<Long, String> getBoardForBoardGroup(
            @RequestParam("parent") int boardGroupId,
            HttpServletRequest request,
            Model model) {
        Map<Long, String> data = new HashMap<>();
        //补上一个空位.大版主不用选择具体的版块
        data.put(0L, "选择版块");
        Map<Long, String> rs = boardService.getAllByVolumesId(boardGroupId).collect(Collectors.toMap(Board::getId, Board::getTitle));
        data.putAll(rs);
        return data;
    }
    //加载版块组和版块的名称
    @GetMapping(path = "/load", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Map<String, CommonBean> dynamicQueryTitleData(
            @RequestParam("volume") int boardGroupId,
            @RequestParam("board") long boardId,
            HttpServletRequest request,
            Model model) {
        Map<String, CommonBean> data = new HashMap<>();
        //
        BoardGroup boardGroup = boardGroupService.get(boardGroupId).orElse(BoardGroup.defaultInstance());
        data.put("volume", new CommonBean(boardGroup.getId(), boardGroup.getTitle()));
        //
        Board board = boardService.get(boardId).orElse(Board.empty(boardId));
        data.put("board", new CommonBean(board.getId(), board.getTitle()));
        return data;
    }
    //加载版块的标题
    @GetMapping(path = "/title", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public CommonBean getBoardTitle(
            @RequestParam("id") long id,
            HttpServletRequest request,
            Model model) {
        if (id == 0) {
            return new CommonBean(0, "所有");
        }
        String title = boardService.get(id).map(Board::getTitle).orElse("版块");
        return new CommonBean(id, title);
    }
}